import random
import time
from functools import wraps

from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.shortcuts import render

# Create your views here.
from django.utils.crypto import salted_hmac
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

from app_server.models import UserLogin


def operate_session(method=None, user_=None, type_="get", session_id=None):
    """
    操作session
    :param user_: 用户
    :param method: 访问登录端口，web，app等
    :param type_: 需要获取session传get， 需要查验session，传check， 查验且获得新的session，传check_get
    :param session_id: check是否存在，以证明是否允许登录。
    :return: 返回False或session_id
    """
    # if type_ == "get":
    #     time_stamp = str(time.time())
    # elif type_ == "check":
    #     pass
    # else:
    #     return False
    # key_salt = method + time_stamp
    # session_id = salted_hmac(key_salt, user_.password).hexdigest()

    if type_ == "get":
        ul, _ = UserLogin.objects.get_or_create(to_user=user_, method=method)
    elif type_ == "check_get":
        try:
            ul = UserLogin.objects.get(session_id=session_id)
        except:
            return False
    elif type_ == "check":
        try:
            ul = UserLogin.objects.get(session_id=session_id)
            return ul.to_user
        except:
            return False
    else:
        return False
    time_stamp = str(time.time())
    key_salt = method + time_stamp
    session_id = salted_hmac(key_salt, ul.to_user.password).hexdigest()
    ul.time_stamp = time_stamp
    ul.session_id = session_id
    ul.save()
    return session_id


@api_view(["GET", ])
def check_get_login(request, method, session_id):
    """
    核对并获取session登录
    :param request:
    :param method: 登录方式web, app等
    :param session_id: 需要验证的session_id
    :return:
    """
    new_session = operate_session(method, type_="check_get", session_id=session_id)
    if new_session:
        return Response({"status": "Session success.", "sessionid": new_session}, status.HTTP_200_OK)

    else:
        return Response("Session error.", status.HTTP_400_BAD_REQUEST)


def check_login(func):
    @wraps(func)
    def warpper(request, *args, **kwargs):
        session_id = request.GET.get("sessionid")
        ops = operate_session(type_="check", session_id=session_id)
        if ops:
            request.user = ops
            return func(request, *args, **kwargs)
        else:
            raise Exception("Session error.", status.HTTP_400_BAD_REQUEST)
            # return Response("Session error.", status.HTTP_400_BAD_REQUEST)
    return warpper


@check_login
@api_view(["GET", ])
def test(request):
    return Response("123")


@api_view(["GET", ])
def sys_login(request, method):
    # if request.method == "GET":
    # try:
    #     user_login = User.objects.get(username=request.GET.get("username", ""))
    # except:
    #     return Response("username is error.", status=status.HTTP_404_NOT_FOUND)
    # is_user = user_login.check_password(request.GET.get("password", ""))
    # if is_user:
    #     login(request, user_login)
    #     return Response("login success", status=status.HTTP_200_OK)
    # return Response("password is error", status=status.HTTP_404_NOT_FOUND)

    user_login = authenticate(username=request.GET.get("username", ""), password=request.GET.get("password", ""))
    if user_login:
        # login(request, user_login)
        # session_auth_hash = user_login.get_session_auth_hash()
        session_auth_hash = operate_session(method, user_login, "get")
        res = Response({"status": "Login success.", "sessionid": session_auth_hash}, status.HTTP_200_OK)
        return res
    else:
        return Response("Checkout your username and password.", status.HTTP_404_NOT_FOUND)


@api_view(["GET", ])
def sys_logout(request):
    try:
        logout(request)
        return Response("logout success", status.HTTP_200_OK)
    except:
        return Response("Logout error. Please checkout is logined.", status.HTTP_404_NOT_FOUND)


@api_view(["GET", ])
def sys_register(request, method):
    username = request.GET.get("username", "")
    password = request.GET.get("password", "")
    try:
        User.username_validator(username)
    except:
        return Response("Username is not validated.", status.HTTP_400_BAD_REQUEST)
    if len(password) < 6:
        return Response("Password is too short. Less than 6.", status.HTTP_400_BAD_REQUEST)

    tmp_user = User(username=username)
    tmp_user.set_password(password)
    try:
        tmp_user.validate_unique(username)
    except:
        return Response("Username has registed.", status.HTTP_400_BAD_REQUEST)
    try:
        tmp_user.save()
        # login(request, tmp_user)
        session_auth_hash = operate_session(method, tmp_user, "get")
    except:
        return Response("register error.", status.HTTP_400_BAD_REQUEST)
    return Response({"status": "Register success.", "sessionid": session_auth_hash}, status.HTTP_200_OK)
